/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = tonglinkq_comm.c                                              */
/*  NOTE      = TongLINK/Q协议解析共通                                        */
/*  DATE      = 2015/07/15 by wuwk                                            */
/******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>

#include "frreport_comm.h"
#include "frbyte_buffer.h"
#include "tonglinkq_core.h"
#include "tonglinkq_comm.h"

#define TLQ_REPORT_KEY                           "tonglinkq."

#define TLQ_JAVA_LANG_NUMBER                     "java.lang.Number"

union int32_float_bits {
    int32_t int_bits;
    float float_bits;
};

union int64_double_bits {
    int64_t int_bits;
    double double_bits;
};

/*******************************************************************************
*  FUNC     :  复制frlist 节点
*  ARGS     :  p_lst_source (源节点)
            :  p_lst_dest(目标节点)
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
void tonglinkq_frlist_copy(Frlist_header *p_lst_source, Frlist_header *p_lst_dest)
{
    Frlist_node *p_st_node_org=NULL, *p_st_node_clone=NULL;
    Frvar_field *p_st_field_org = NULL, *p_st_field_clone=NULL;

    p_st_node_org = FRLIST_FIRST_NODE(p_lst_source);

    while(p_st_node_org)
    {
        p_st_field_org =  (Frvar_field*)FRLIST_GET_NODE_DATA(p_st_node_org);
        p_st_field_clone = frvarfield_clone(p_st_field_org);
        if(p_st_field_clone)
        {
            p_st_node_clone = frlist_node_create(p_st_field_clone);
            if(p_st_node_clone == NULL)
                frvarfield_free(&p_st_field_clone);
            else
                frlist_push(p_lst_dest, p_st_node_clone);
        }

        p_st_node_org = FRLIST_NEXT_NODE(p_st_node_org);
    }

    return;
}

/*******************************************************************************
*  FUNC     :  复制L7 数据
*  ARGS     :  p_st_src (源数据)
            :  pp_st_dst(目标数据)
*  RTN      :  int
*  NOTE     :
*******************************************************************************/
int tonglinkq_body_l7data_copy(Frreport_body_data *p_st_src
                                         , Frreport_body_data **pp_st_dst)
{
    Frlist_header *p_lst = NULL;
    Frreport_body_data *p_st_dst = NULL;
    Frreport_l7data *p_st_l7data_src = NULL;

    if (p_st_src == NULL)
        return FR_FAIL;

    p_st_dst = (Frreport_body_data *)frmalloc(sizeof(Frreport_body_data));
    if (p_st_dst == NULL)
        goto err;

    memset(p_st_dst, 0x00, sizeof(Frreport_body_data));
    p_st_l7data_src = &(p_st_src->un_data.st_l7data);

    p_st_dst->em_type = p_st_src->em_type;
    p_st_dst->un_data.st_l7data.ip_proto = p_st_l7data_src->ip_proto;
    p_st_dst->un_data.st_l7data.src_ip = p_st_l7data_src->src_ip;
    p_st_dst->un_data.st_l7data.src_port = p_st_l7data_src->src_port;
    p_st_dst->un_data.st_l7data.dst_ip = p_st_l7data_src->dst_ip;
    p_st_dst->un_data.st_l7data.dst_port = p_st_l7data_src->dst_port;
    p_st_dst->un_data.st_l7data.i_l7_proto = p_st_l7data_src->i_l7_proto;

    /* 请求数据 */
    p_lst = FRREPORT_BODY_L7LIST_CLONE_REQ(p_st_src);
    if (p_lst == NULL)
        goto err;
    tonglinkq_frlist_copy(p_lst, &p_st_dst->un_data.st_l7data.st_hdr_req);

    frreport_body_l7list_free(&p_lst);

    /* session数据 */
    p_lst = FRREPORT_BODY_L7LIST_CLONE_COMM(p_st_src);
    if (p_lst == NULL)
        goto err;
    tonglinkq_frlist_copy(p_lst, &p_st_dst->un_data.st_l7data.st_hdr_comm);

    frreport_body_l7list_free(&p_lst);

    /* mq数据 */
    p_lst = FRREPORT_BODY_L7LIST_CLONE_MQ(p_st_src);
    if (p_lst == NULL)
        goto err;
    tonglinkq_frlist_copy(p_lst, &p_st_dst->un_data.st_l7data.st_hdr_mq);

    frreport_body_l7list_free(&p_lst);

    *pp_st_dst = p_st_dst;

    return FR_SUCC;

err:
    if (p_st_dst)
        frfree(p_st_dst);

    if (p_lst)
        frreport_body_l7list_free(&p_lst);

    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  取得对应的请求
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_ul_seq(seq)
            :  p_i_responserequired(是否需要应答)
            :  p_st_l4_trans(传输信息)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
Frreport_body_data *tonglinkq_get_req_node(L7session_tonglinkq_private *p_st_private
                                         , unsigned long *p_ul_seq
                                         , int *p_i_responserequired
                                         , L4_transaction *p_st_l4_trans
                                         , char **pp_title)
{
    Tonglinkq_frbyte_resp *p_st_resp = NULL;
    Tonglinkq_frbyte_req *p_st_req_node = NULL;
    Tonglinkq_frbyte_req_list *p_lst_node = NULL;
    Tonglinkq_frbyte_req_list *p_lst_node_next = NULL;
    Frreport_body_data *p_st_body_data = NULL;
    int i = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_lst_req == NULL
        || p_st_private->p_st_resp == NULL || p_st_l4_trans == NULL)
        return NULL;

    p_st_resp = p_st_private->p_st_resp;
    if (p_st_resp->i_asyn_flag == 0)
    {
        p_lst_node_next = p_st_private->p_lst_req;
        /* 取最后一个节点 */
        while (p_lst_node_next)
        {
            i++;
            p_lst_node = p_lst_node_next;
            p_lst_node_next = p_lst_node->next;
        }
        if (p_lst_node)
            p_st_req_node = p_lst_node->p_st_node;
    }
    else
    {
        p_lst_node = p_st_private->p_lst_req;
        while (p_lst_node)
        {
            i++;
            p_st_req_node = p_lst_node->p_st_node;
            /* 请求和响应的MsgId一致 */
            if (strncasecmp(p_st_req_node->msgid, p_st_resp->msgid, TLQ_MSGIDLEN) == 0)
            {
                break;
            }
            p_lst_node = p_lst_node->next;
        }
    }

    if (p_lst_node == NULL)
        return NULL;

    i_ret = tonglinkq_body_l7data_copy(p_st_req_node->p_st_body_data_req, &p_st_body_data);
    if (i_ret == FR_FAIL)
        return NULL;

    p_st_private->i_index = i;
    *p_ul_seq = p_st_req_node->ul_seq;
    *p_i_responserequired = p_st_req_node->i_responserequired;
    *pp_title = p_st_req_node->p_title;
    memcpy(p_st_l4_trans, &(p_st_req_node->st_trans_info.st_l4_trans), sizeof(L4_transaction));

    return p_st_body_data;
}

/*******************************************************************************
*  FUNC     :  String型添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_name(属性名)
            :  p_data(内容)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_add_frlist_string(Frreport_body_data *p_st_body_data
                              , char *p_name
                              , char *p_data
                              , int i_req_resp)
{
    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_name == NULL || p_data == NULL)
        return FR_FAIL;

    memset(arr_key, 0x00, sizeof(arr_key));
    if (i_req_resp == TLQ_REQUEST)
        strcpy(arr_key, "request.");
    else
        strcpy(arr_key, "response.");
    strcat(arr_key, TLQ_REPORT_KEY);
    strcat(arr_key, p_name);
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_data);

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  数字型添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_name(属性名)
            :  i_value(值)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_add_frlist_int(Frreport_body_data *p_st_body_data
                           , char *p_name
                           , int i_value
                           , int i_req_resp)
{
    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_name == NULL)
        return FR_FAIL;

    memset(arr_key, 0x00, sizeof(arr_key));
    if (i_req_resp == TLQ_REQUEST)
        strcpy(arr_key, "request.");
    else
        strcpy(arr_key, "response.");
    strcat(arr_key, TLQ_REPORT_KEY);
    strcat(arr_key, p_name);
    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, i_value);

    return i_ret;
}


/*******************************************************************************
*  FUNC     :  取short数据并添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_index(索引)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_short(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, int i_index)
{
    uint16_t u16_len = 0;
    char arr_value[16];
//    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_value, sizeof(arr_value), "%d:%d", i_index, u16_len);
    i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"short", arr_value, TLQ_REQUEST);
//    snprintf(arr_key, sizeof(arr_key), "%s.1.short.%d", MQ_MESSAGE_REQ, i_index);
//    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, u16_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取long型数据并添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_index(索引)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_long(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, int i_index)
{
    uint64_t u64_len = 0;
    char arr_value[16];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_value, sizeof(arr_value), "%d:%ld", i_index, u64_len);
    i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"long", arr_value, TLQ_REQUEST);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取int型数据并添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_index(索引)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_int(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, int i_index)
{
    uint32_t u32_len = 0;
    char arr_value[16];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_value, sizeof(arr_value), "%d:%d", i_index, u32_len);
    i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"int", arr_value, TLQ_REQUEST);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取float型数据并添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_index(索引)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_float(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, int i_index)
{
    uint32_t u32_len = 0;
    float f_value = 0.0;
    char arr_value[64];
    union int32_float_bits u_32bits;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    u_32bits.int_bits = u32_len;
    f_value = u_32bits.float_bits;
    snprintf(arr_value, sizeof(arr_value), "%d:%f", i_index, f_value);
    i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"float", arr_value, TLQ_REQUEST);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取double型数据并添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_index(索引)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_double(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, int i_index)
{
    uint64_t u64_len = 0;
    double db_value = 0.0;
    char arr_value[64];
    union int64_double_bits u_64bits;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    u_64bits.int_bits = u64_len;
    db_value = u_64bits.double_bits;
    snprintf(arr_value, sizeof(arr_value), "%d:%lf", i_index, db_value);
    i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"double", arr_value, TLQ_REQUEST);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 8);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取char型数据并添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_index(索引)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_char(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, int i_index)
{
    uint8_t u8_char = 0;
    char arr_value[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_char);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_value, sizeof(arr_value), "%d:%c", i_index, u8_char);
    i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"char", arr_value, TLQ_REQUEST);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取string型数据并添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_index(索引)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_string(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, int i_index)
{
    uint32_t u32_len = 0;
    char *p_data = NULL;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    /* 长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    p_data = (char *)frmalloc(u32_len + 1 + 16);
    if (p_data == NULL)
        return FR_FAIL;
    memset(p_data, 0x00, u32_len + 1 + 16);

    snprintf(p_data, u32_len + 1 + 16, "%d:", i_index);
    i_ret = bytebuff_get_bytes(p_st_data, p_data+strlen(p_data), u32_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_data);
        return FR_FAIL;
    }

    i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"string", p_data, TLQ_REQUEST);
    frfree(p_data);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取carray型数据并添加到链表
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_index(索引)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_carray(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, int i_index)
{
    uint32_t u32_len = 0;
    char *p_data = NULL;
    int i_len = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    /* 长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    p_data = (char *)frmalloc(u32_len + 1 + 16);
    if (p_data == NULL)
        return FR_FAIL;
    memset(p_data, 0x00, u32_len + 1 + 16);

    snprintf(p_data, u32_len + 1 + 16, "%d:", i_index);
    i_len = strlen(p_data);
    i_ret = bytebuff_get_bytes(p_st_data, p_data+i_len, u32_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_data);
        return FR_FAIL;
    }

    i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"carray", p_data, TLQ_REQUEST);
    frfree(p_data);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取MAP的boolean型数据并添加到链表
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_key(上报key)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_map_boolean(Frreport_body_data *p_st_body_data
                            , Frbyte_Packet *p_st_data
                            , char *p_key)
{
    uint8_t u8_value = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    /* 取boolean值 */
    i_ret = bytebuff_get_char(p_st_data, &u8_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 上报 */
    i_ret = frreport_body_l7_add_int(p_st_body_data, p_key, u8_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取MAP的char型数据并添加到链表
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_key(上报key)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_map_char(Frreport_body_data *p_st_body_data
                         , Frbyte_Packet *p_st_data
                         , char *p_key)
{
    uint8_t u8_value = 0;
    char arr_str[2];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 1);
    /* 取char值 */
    i_ret = bytebuff_get_char(p_st_data, &u8_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_str, sizeof(arr_str), "%c", u8_value);
    /* 上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, arr_str);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取MAP的short型数据并添加到链表
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_key(上报key)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_map_short(Frreport_body_data *p_st_body_data
                          , Frbyte_Packet *p_st_data
                          , char *p_key)
{
    uint16_t u16_value = 0;
    int i_index = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data)
                                        , bytebuff_getPosition(p_st_data)+19
                                        , TLQ_JAVA_LANG_NUMBER, 16, &i_index);
    if (i_ret == FR_SUCC)
        /* 31=18+13 */
        bytebuff_skip(p_st_data, 31);
    else
        bytebuff_skip(p_st_data, 4);

    /* 取short值 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_value, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 上报 */
    i_ret = frreport_body_l7_add_int(p_st_body_data, p_key, u16_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取MAP的int型数据并添加到链表
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_key(上报key)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_map_int(Frreport_body_data *p_st_body_data
                        , Frbyte_Packet *p_st_data
                        , char *p_key)
{
    uint32_t u32_value = 0;
    int i_index = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data)
                          , bytebuff_getPosition(p_st_data)+19
                          , TLQ_JAVA_LANG_NUMBER, 16, &i_index);
    if (i_ret == FR_SUCC)
        /* 31=18+13 */
        bytebuff_skip(p_st_data, 31);
    else
        bytebuff_skip(p_st_data, 4);

    /* 取int值 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 上报 */
    i_ret = frreport_body_l7_add_int(p_st_body_data, p_key, u32_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取MAP的long型数据并添加到链表
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_key(上报key)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_map_long(Frreport_body_data *p_st_body_data
                         , Frbyte_Packet *p_st_data
                         , char *p_key)
{
    uint64_t u64_value = 0;
    int i_index = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data)
                          , bytebuff_getPosition(p_st_data)+19
                          , TLQ_JAVA_LANG_NUMBER, 16, &i_index);
    if (i_ret == FR_SUCC)
        /* 31=18+13 */
        bytebuff_skip(p_st_data, 31);
    else
        bytebuff_skip(p_st_data, 4);

    i_ret = bytebuff_get_long(p_st_data, 8, &u64_value, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 上报 */
    i_ret = frreport_body_l7_add_int(p_st_body_data, p_key, u64_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取MAP的float型数据并添加到链表
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_key(上报key)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_map_float(Frreport_body_data *p_st_body_data
                          , Frbyte_Packet *p_st_data
                          , char *p_key)
{
    uint32_t u32_value = 0;
    union int32_float_bits u_32bits;
    float f_value = 0.0;
    int i_index = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data)
                          , bytebuff_getPosition(p_st_data)+19
                          , TLQ_JAVA_LANG_NUMBER, 16, &i_index);
    if (i_ret == FR_SUCC)
        /* 31=18+13 */
        bytebuff_skip(p_st_data, 31);
    else
        bytebuff_skip(p_st_data, 4);

    /* 取float值 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    u_32bits.int_bits = u32_value;
    f_value = u_32bits.float_bits;

    /* 上报 */
    i_ret = frreport_body_l7_add_float(p_st_body_data, p_key, f_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取MAP的double型数据并添加到链表
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_key(上报key)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_map_double(Frreport_body_data *p_st_body_data
                           , Frbyte_Packet *p_st_data
                           , char *p_key)
{
    uint64_t u64_value = 0;
    double db_value = 0.0;
    union int64_double_bits u_64bits;
    int i_index = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data)
                          , bytebuff_getPosition(p_st_data)+19
                          , TLQ_JAVA_LANG_NUMBER, 16, &i_index);
    if (i_ret == FR_SUCC)
        /* 31=18+13 */
        bytebuff_skip(p_st_data, 31);
    else
        bytebuff_skip(p_st_data, 4);

    i_ret = bytebuff_get_long(p_st_data, 8, &u64_value, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    u_64bits.int_bits = u64_value;
    db_value = u_64bits.double_bits;

    /* 上报 */
    i_ret = frreport_body_l7_add_double(p_st_body_data, p_key, db_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取MAP的byte型数据并添加到链表
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_key(上报key)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_get_map_byte(Frreport_body_data *p_st_body_data
                         , Frbyte_Packet *p_st_data
                         , char *p_key)
{
    uint8_t u8_value = 0;
    char arr_str[5];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 4);
    /* 取byte值 */
    i_ret = bytebuff_get_char(p_st_data, &u8_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_str, sizeof(arr_str), "%d", u8_value);
    /* 上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, arr_str);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}
